#include "anillo.h"
#include "aed2_tests.h"

template<typename T>
string to_s(const Anillo<T>* a) {
	ostringstream os;
	os << *a;
	return os.str();
}

void AnilloNuevoEsVacio() {
	Anillo<int>* a = new Anillo<int>();
	ASSERT(a->esVacio());
	ASSERT_EQ(a->tamanio(), 0);
	delete a;
}

void AnilloUnitarioAlEliminarQuedaVacio() {
	Anillo<int>* a = new Anillo<int>();
	ASSERT(a->esVacio());
	ASSERT_EQ(a->tamanio(), 0);
    a->agregar(42);
	ASSERT(!a->esVacio());
	ASSERT_EQ(a->tamanio(), 1);
    a->eliminar(42);
	ASSERT(a->esVacio());
	ASSERT_EQ(a->tamanio(), 0);
	delete a;
}

void AnilloUnitarioDaSiguiente() {
	Anillo<int>* a = new Anillo<int>();
    a->agregar(42);
    ASSERT(!a->esVacio());
    ASSERT_EQ(a->tamanio(), 1);
    ASSERT_EQ(a->siguiente(), 42);
	delete a;
}

void MostrarAnilloVacio() {
	Anillo<int>* a = new Anillo<int>();
	ASSERT_EQ(to_s(a), "[]");
	delete a;
}

void MostrarAnillo1() {
	Anillo<int>* a = new Anillo<int>();
    a->agregar(1);
    a->agregar(2);
    a->agregar(3);
    a->agregar(4);
	ASSERT_EQ(to_s(a), "[4,3,2,1]");
    Anillo<int> *b = new Anillo<int>(*a);
    b->agregar(5);
	ASSERT_EQ(to_s(b), "[5,4,3,2,1]");
	ASSERT_EQ(to_s(a), "[4,3,2,1]");
	ASSERT_EQ(a->siguiente(),3);
	ASSERT_EQ(a->siguiente(),2);
	ASSERT(!a->hayMarcado());
	a->marcar();
	ASSERT(a->hayMarcado());
	ASSERT_EQ(a->siguiente(),1);
	ASSERT_EQ(a->siguiente(),4);
	ASSERT_EQ(a->siguiente(),3);
	ASSERT_EQ(to_s(a), "[3,2*,1,4]");
	ASSERT_EQ(a->marcado(),2);
    b->eliminar(5);
	ASSERT_EQ(to_s(b), "[4,3,2,1]");
    a->eliminar(2);
	ASSERT_EQ(to_s(a), "[3,1,4]");
	ASSERT(!a->hayMarcado());

	delete a;
	delete b;
}


void CompararAnillos() {
	Anillo<int>* a = new Anillo<int>();
    a->agregar(1);
    a->agregar(2);
    a->agregar(3);
    a->marcar();
    a->agregar(3);
	ASSERT_EQ(to_s(a), "[3,3*,2,1]");
    Anillo<int> *b = new Anillo<int>(*a);
    Anillo<int> *c = new Anillo<int>(*a);
    ASSERT(*a == *b);
    ASSERT(*a == *c);
    b->agregar(5);
	ASSERT_EQ(to_s(b), "[5,3,3*,2,1]");
    ASSERT(!(*a == *b));
    c->marcar();
	ASSERT_EQ(to_s(c), "[3*,3,2,1]");
    ASSERT(!(*a == *c));
    a->eliminar(3);
    c->eliminar(3);
    ASSERT(!a->hayMarcado())
	ASSERT_EQ(to_s(c), "[2,1]");
    ASSERT((*a == *c));
	b->retroceder();
	ASSERT_EQ(to_s(b), "[3,3*,2,1,5]");
	b->retroceder();
	b->retroceder();
	ASSERT_EQ(to_s(b), "[2,1,5,3,3*]");

	delete a;
	delete b;
	delete c;
}


int main(void) {
	RUN_TEST(AnilloNuevoEsVacio);
    RUN_TEST(AnilloUnitarioAlEliminarQuedaVacio);
	RUN_TEST(AnilloUnitarioDaSiguiente);
    RUN_TEST(MostrarAnilloVacio);
    RUN_TEST(MostrarAnillo1);
    RUN_TEST(CompararAnillos);

	return 0;
}

